1AutoGridLayoutManager
2PageIndicatorView
3PageRecyclerView
4使用
首先看需求效果 在acvitity中有一个控件,需要实现这种分页效果,还要指示器,并且每页的两列不能太分散,使用GridView就很不好实现,这里用RecycleView展示,先看成型后需要用到的结构(需要用到哪些自定义的东西) 自己在Java下建一个新的包,需要这三个自定义的东西,一个用来展示GridView布局样式自定义的GridViewLayoutManger,一个指示器的自定义控件,第三个就是自定义RecleView,实现翻页效果,另外还有一个工具类,实现获取屏幕尺寸,并且让px和dp相互转换的功能,网上有很多,没有几行代码,之前也专门写过,不再赘述,接下来就看着三个自定义东西怎么写
1、AutoGridLayoutManager
package inditor.recycleview.horizontal;
import android.content.Context;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by YTF on 2017/9/16.
*/
public class AutoGridLayoutManager extends GridLayoutManager {
private int measuredWidth = 0;
private int measuredHeight = 0;
public AutoGridLayoutManager(Context context, AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public AutoGridLayoutManager(Context context, int spanCount) {
super(context, spanCount);
}
public AutoGridLayoutManager(Context context, int spanCount,
int orientation, boolean reverseLayout) {
super(context, spanCount, orientation, reverseLayout);
}
@Override
public void onMeasure(RecyclerView.Recycler recycler,
RecyclerView.State state, int widthSpec, int heightSpec) {
if (measuredHeight 0){
View view = recycler.getViewForPosition(0);
if (view != null) {
measureChild(view, widthSpec, heightSpec);
measuredWidth = View.MeasureSpec.getSize(widthSpec);
measuredHeight = view.getMeasuredHeight() * getSpanCount();
}
}
}
setMeasuredDimension(measuredWidth, measuredHeight);
}
}
2、PageIndicatorView
package inditor.recycleview.horizontal;
import android.content.Context;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;
import com.lab.web.entity.UtilDynamicWidth;
import java.util.ArrayList;
import java.util.List;
/**
* Created by shichaohui on 2015/7/10 0010.
*
* 页码指示器类,获得此类实例后,可通过{@link PageIndicatorView#initIndicator(int)}方法初始化指示器
*
*/
public class PageIndicatorView extends LinearLayout {
private Context mContext = null;
private int dotSize = 10; // 指示器的大小(dp)
private int margins = 10; // 指示器间距(dp)
private List indicatorViews = null; // 存放指示器
public PageIndicatorView(Context context) {
this(context, null);
}
public PageIndicatorView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PageIndicatorView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
this.mContext = context;
setGravity(Gravity.CENTER);
setOrientation(HORIZONTAL);
dotSize = UtilDynamicWidth.dip2px(context, dotSize);
margins = UtilDynamicWidth.dip2px(context, margins);
}
/**
* 初始化指示器,默认选中第一页
*
* @param count 指示器数量,即页数
*/
public void initIndicator(int count) {
if (indicatorViews == null) {
indicatorViews = new ArrayList();
} else {
indicatorViews.clear();
removeAllViews();
}
View view;
LayoutParams params = new LayoutParams(dotSize, dotSize);
params.setMargins(margins, margins, margins, margins);
for (int i = 0; i < count; i++) {
view = new View(mContext);
view.setBackgroundResource(android.R.drawable.presence_invisible);
addView(view, params);
indicatorViews.add(view);
}
if (indicatorViews.size() > 0) {
indicatorViews.get(0).setBackgroundResource(android.R.drawable.presence_online);
}
}
/**
* 设置选中页
*
* @param selected 页下标,从0开始
*/
public void setSelectedPage(int selected) {
for (int i = 0; i < indicatorViews.size(); i++) {
if (i == selected) {
indicatorViews.get(i).setBackgroundResource(android.R.drawable.presence_online);
} else {
indicatorViews.get(i).setBackgroundResource(android.R.drawable.presence_invisible);
}
}
}
}
3、PageRecyclerView
package inditor.recycleview.horizontal;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import com.lab.web.entity.UtilDynamicWidth;
import java.util.List;
import java.util.Map;
/**
* Created by shichaohui on 2015/7/9 0009.
*
* 横向分页的GridView效果
*
*
* 默认为1行,每页3列,如果要自定义行数和列数,请在调用{@link PageRecyclerView#setAdapter(Adapter)}方法前调用
* {@link PageRecyclerView#setPageSize(int, int)}方法自定义行数
*
*/
public class PageRecyclerView extends RecyclerView {
private Context mContext = null;
private PageAdapter myAdapter = null;
private int shortestDistance; // 超过此距离的滑动才有效
private float slideDistance = 0; // 滑动的距离
private float scrollX = 0; // X轴当前的位置
private int spanRow = 1; // 行数
private int spanColumn = 2; // 每页列数
private int totalPage = 0; // 总页数
private int currentPage = 1; // 当前页
private int pageMargin = 0; // 页间距
private PageIndicatorView mIndicatorView = null; // 指示器布局
private int realPosition = 0; // 真正的位置(从上到下从左到右的排列方式变换成从左到右从上到下的排列方式后的位置)
/*
* 0: 停止滚动且手指移开; 1: 开始滚动; 2: 手指做了抛的动作(手指离开屏幕前,用力滑了一下)
*/
private int scrollState = 0; // 滚动状态
public PageRecyclerView(Context context) {
this(context, null);
}
public PageRecyclerView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PageRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
defaultInit(context);
}
// 默认初始化
private void defaultInit(Context context) {
this.mContext = context;
setLayoutManager(new AutoGridLayoutManager(
mContext, spanRow, AutoGridLayoutManager.HORIZONTAL, false));
setOverScrollMode(OVER_SCROLL_NEVER);
}
/**
* 设置行数和每页列数
*
* @param spanRow 行数, |